package com.jikangjun.disk.email;

import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.SimpleEmail;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Service
public class EmailServiceImpl implements EmailService {
    // 存储验证码（区分场景：key=场景+邮箱，如"register_user@example.com"、"find_user@example.com"）
    private static final ConcurrentHashMap<String, String> VERIFICATION_CODES = new ConcurrentHashMap<>();
    // 验证码过期时间（分钟）
    private static final int CODE_EXPIRATION_MINUTES = 5;
    // 定时清理过期验证码的线程池
    private static final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

    static {
        // 每小时清理一次过期验证码（避免内存溢出）
        scheduler.scheduleAtFixedRate(VERIFICATION_CODES::clear, 1, 1, TimeUnit.HOURS);
    }

    // 邮件服务器配置（注册场景使用commons-email）
    @Value("${mail.host.name}")
    private String hostName;

    @Value("${mail.from.user}")
    private String fromUser;

    @Value("${mail.from.pwd}")
    private String fromPwd;

    // 邮件发送器（找回密码场景使用Spring Mail）
    @Autowired
    private JavaMailSender mailSender;

    // 注册场景：发送验证码（使用commons-email）
    @Override
    public String sendEmailCode(String email) {
        String code = generateVerificationCode();
        String key = "register_" + email;
        VERIFICATION_CODES.put(key, code);

        try {
            SimpleEmail simpleEmail = new SimpleEmail();
            simpleEmail.setHostName(hostName);
            simpleEmail.setSmtpPort(465); // 修复：163邮箱推荐使用465端口（SSL加密）
            simpleEmail.setSSLOnConnect(true); // 修复：启用SSL加密
            simpleEmail.setAuthentication(fromUser, fromPwd); // 发件人账号与授权账号一致
            simpleEmail.setFrom(fromUser, "系统管理员"); // 修复：确保发件人地址与授权账号一致
            simpleEmail.addTo(email);
            simpleEmail.setSubject("注册验证码");
            simpleEmail.setMsg("您的注册验证码是：" + code + "，有效期5分钟。");
            simpleEmail.send();
            System.out.println("发送注册验证码到邮箱: " + email + "，验证码: " + code);
        } catch (EmailException e) {
            e.printStackTrace();
            throw new RuntimeException("发送邮件失败：" + e.getMessage());
        }

        return code;
    }

    // 注册场景：验证验证码
    @Override
    public boolean verifyEmailCode(String email, String code) {
        String key = "register_" + email;
        String storedCode = VERIFICATION_CODES.get(key);
        if (storedCode != null && storedCode.equals(code)) {
            VERIFICATION_CODES.remove(key);
            return true;
        }
        return false;
    }

    /**
     * 生成6位数字验证码
     */
    private String generateVerificationCode() {
        Random random = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 6; i++) {
            sb.append(random.nextInt(10));
        }
        return sb.toString();
    }

    // 找回密码场景：发送验证码（使用Spring Mail）
    @Override
    public boolean sendCode(String email, String scene) {
        String code = generateVerificationCode();
        String key = scene + email;
        VERIFICATION_CODES.put(key, code);

        // 定时删除验证码（过期自动失效）
        scheduler.schedule(() -> VERIFICATION_CODES.remove(key), CODE_EXPIRATION_MINUTES, TimeUnit.MINUTES);

        try {
            SimpleMailMessage message = new SimpleMailMessage();
            message.setTo(email);
            message.setSubject("找回密码验证码");
            message.setText("您的验证码是：" + code + "，5分钟内有效，请勿泄露给他人。");
            message.setFrom(fromUser); // 确保发件人地址与配置的授权账号一致
            mailSender.send(message);
            System.out.println("发送找回密码验证码到邮箱: " + email + "，验证码: " + code);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    // 找回密码场景：验证验证码
    @Override
    public boolean verifyCode(String email, String code, String scene) {
        String key = scene + email;
        String storedCode = VERIFICATION_CODES.get(key);
        if (code != null && code.equals(storedCode)) {
            VERIFICATION_CODES.remove(key);
            return true;
        }
        return false;
    }
}
